[LINUX] Extend the event-channel interfaces to provide helper methods
authorkaf24@localhost.localdomain <kaf24@localhost.localdomain>
Sat, 30 Dec 2006 18:23:27 +0000 (18:23 +0000)
committerkaf24@localhost.localdomain <kaf24@localhost.localdomain>
Sat, 30 Dec 2006 18:23:27 +0000 (18:23 +0000)
for creating interdomain event channels bound to IRQ handlers.
Signed-off-by: Keir Fraser <keir@xensource.com>
21 files changed:
linux-2.6-xen-sparse/drivers/char/tpm/tpm_xen.c
linux-2.6-xen-sparse/drivers/xen/blkback/common.h
linux-2.6-xen-sparse/drivers/xen/blkback/interface.c
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
linux-2.6-xen-sparse/drivers/xen/blkfront/block.h
linux-2.6-xen-sparse/drivers/xen/blktap/common.h
linux-2.6-xen-sparse/drivers/xen/blktap/interface.c
linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c
linux-2.6-xen-sparse/drivers/xen/core/evtchn.c
linux-2.6-xen-sparse/drivers/xen/fbfront/xenfb.c
linux-2.6-xen-sparse/drivers/xen/fbfront/xenkbd.c
linux-2.6-xen-sparse/drivers/xen/netback/common.h
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
linux-2.6-xen-sparse/drivers/xen/pciback/xenbus.c
linux-2.6-xen-sparse/drivers/xen/tpmback/common.h
linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_client.c
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c
linux-2.6-xen-sparse/include/xen/evtchn.h
linux-2.6-xen-sparse/include/xen/xenbus.h

index adf016ba90997f34817abb178f19d0ec7b278bab..cdbc7decd773f44c1a888735679ac7321d14d374 100644 (file)
@@ -54,7 +54,6 @@ struct tpm_private {
 
        tpmif_tx_interface_t *tx;
        atomic_t refcnt;
-       unsigned int evtchn;
        unsigned int irq;
        u8 is_connected;
        u8 is_suspended;
@@ -271,7 +270,7 @@ static void destroy_tpmring(struct tpm_private *tp)
        if (tp->irq)
                unbind_from_irqhandler(tp->irq, tp);
 
-       tp->evtchn = tp->irq = 0;
+       tp->irq = 0;
 }
 
 
@@ -302,8 +301,8 @@ again:
                goto abort_transaction;
        }
 
-       err = xenbus_printf(xbt, dev->nodename,
-                           "event-channel", "%u", tp->evtchn);
+       err = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
+                           irq_to_evtchn_port(tp->irq));
        if (err) {
                message = "writing event-channel";
                goto abort_transaction;
@@ -459,19 +458,15 @@ static int tpmif_connect(struct xenbus_device *dev,
 
        tp->backend_id = domid;
 
-       err = xenbus_alloc_evtchn(dev, &tp->evtchn);
-       if (err)
-               return err;
-
-       err = bind_evtchn_to_irqhandler(tp->evtchn,
-                                       tpmif_int, SA_SAMPLE_RANDOM, "tpmif",
-                                       tp);
+       err = bind_listening_port_to_irqhandler(
+               domid, tpmif_int, SA_SAMPLE_RANDOM, "tpmif", tp);
        if (err <= 0) {
-               WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
+               WPRINTK("bind_listening_port_to_irqhandler failed "
+                       "(err=%d)\n", err);
                return err;
        }
-
        tp->irq = err;
+
        return 0;
 }
 
@@ -656,9 +651,6 @@ static int tpm_xmit(struct tpm_private *tp,
 
        mb();
 
-       DPRINTK("Notifying backend via event channel %d\n",
-               tp->evtchn);
-
        notify_remote_via_irq(tp->irq);
 
        spin_unlock_irq(&tp->tx_lock);
index 1b5b6a427e9035b1c91cdcab9691691c0b98f703..1c51768bb7c585ec7d04f4352a4f133a42702a82 100644 (file)
@@ -65,7 +65,6 @@ typedef struct blkif_st {
        domid_t           domid;
        unsigned int      handle;
        /* Physical parameters of the comms window. */
-       unsigned int      evtchn;
        unsigned int      irq;
        /* Comms information. */
        blkif_back_ring_t blk_ring;
index 53b4764c42e7542741918435f121c47beb576d2c..12552fb17a37e80b9c9216805a552e3464e9e5a4 100644 (file)
@@ -97,7 +97,6 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
 {
        blkif_sring_t *sring;
        int err;
-       struct evtchn_bind_interdomain bind_interdomain;
 
        /* Already connected through? */
        if (blkif->irq)
@@ -112,24 +111,18 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
                return err;
        }
 
-       bind_interdomain.remote_dom  = blkif->domid;
-       bind_interdomain.remote_port = evtchn;
+       sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
+       BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
 
-       err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
-                                         &bind_interdomain);
-       if (err) {
+       err = bind_interdomain_evtchn_to_irqhandler(
+               blkif->domid, evtchn, blkif_be_int, 0, "blkif-backend", blkif);
+       if (err < 0)
+       {
                unmap_frontend_page(blkif);
                free_vm_area(blkif->blk_ring_area);
                return err;
        }
-
-       blkif->evtchn = bind_interdomain.local_port;
-
-       sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
-       BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
-
-       blkif->irq = bind_evtchn_to_irqhandler(
-               blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif);
+       blkif->irq = err;
 
        return 0;
 }
index 6b7100a1bc99042ecb3624bc37ee96d1de27ebca..ff1425980916f18b88d9a6ae3dacff233a435973 100644 (file)
@@ -174,8 +174,8 @@ again:
                message = "writing ring-ref";
                goto abort_transaction;
        }
-       err = xenbus_printf(xbt, dev->nodename,
-                           "event-channel", "%u", info->evtchn);
+       err = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
+                           irq_to_evtchn_port(info->irq));
        if (err) {
                message = "writing event-channel";
                goto abort_transaction;
@@ -228,15 +228,11 @@ static int setup_blkring(struct xenbus_device *dev,
        }
        info->ring_ref = err;
 
-       err = xenbus_alloc_evtchn(dev, &info->evtchn);
-       if (err)
-               goto fail;
-
-       err = bind_evtchn_to_irqhandler(
-               info->evtchn, blkif_int, SA_SAMPLE_RANDOM, "blkif", info);
+       err = bind_listening_port_to_irqhandler(
+               dev->otherend_id, blkif_int, SA_SAMPLE_RANDOM, "blkif", info);
        if (err <= 0) {
                xenbus_dev_fatal(dev, err,
-                                "bind_evtchn_to_irqhandler failed");
+                                "bind_listening_port_to_irqhandler");
                goto fail;
        }
        info->irq = err;
@@ -775,8 +771,7 @@ static void blkif_free(struct blkfront_info *info, int suspend)
        }
        if (info->irq)
                unbind_from_irqhandler(info->irq, info);
-       info->evtchn = info->irq = 0;
-
+       info->irq = 0;
 }
 
 static void blkif_completion(struct blk_shadow *s)
index b86360f405316872a0123b8ccf970239659576bf..6747051cc539d202c51d809fae5339aedda6600e 100644 (file)
@@ -119,7 +119,7 @@ struct blkfront_info
        int connected;
        int ring_ref;
        blkif_front_ring_t ring;
-       unsigned int evtchn, irq;
+       unsigned int irq;
        struct xlbd_major_info *mi;
        request_queue_t *rq;
        struct work_struct work;
index 56faca7a606aa2e2803ffb88ab57f3bca1221ea6..fc42c63508c8eb8813cd5242e780efd83d8d1bb4 100644 (file)
@@ -56,7 +56,6 @@ typedef struct blkif_st {
        domid_t           domid;
        unsigned int      handle;
        /* Physical parameters of the comms window. */
-       unsigned int      evtchn;
        unsigned int      irq;
        /* Comms information. */
        blkif_back_ring_t blk_ring;
index b0eccf4225747f3607677b75a44268b07ab62737..44f653ba516dbcfed8e5bfa648e7becb71ce2087 100644 (file)
@@ -98,7 +98,6 @@ int tap_blkif_map(blkif_t *blkif, unsigned long shared_page,
 {
        blkif_sring_t *sring;
        int err;
-       struct evtchn_bind_interdomain bind_interdomain;
 
        /* Already connected through? */
        if (blkif->irq)
@@ -113,24 +112,18 @@ int tap_blkif_map(blkif_t *blkif, unsigned long shared_page,
                return err;
        }
 
-       bind_interdomain.remote_dom  = blkif->domid;
-       bind_interdomain.remote_port = evtchn;
+       sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
+       BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
 
-       err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
-                                         &bind_interdomain);
-       if (err) {
+       err = bind_interdomain_evtchn_to_irqhandler(
+               blkif->domid, evtchn, tap_blkif_be_int,
+               0, "blkif-backend", blkif);
+       if (err < 0) {
                unmap_frontend_page(blkif);
                free_vm_area(blkif->blk_ring_area);
                return err;
        }
-
-       blkif->evtchn = bind_interdomain.local_port;
-
-       sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
-       BACK_RING_INIT(&blkif->blk_ring, sring, PAGE_SIZE);
-
-       blkif->irq = bind_evtchn_to_irqhandler(
-               blkif->evtchn, tap_blkif_be_int, 0, "blkif-backend", blkif);
+       blkif->irq = err;
 
        return 0;
 }
index a39a22a6d4009223f173aa98a89dd786f8d32ddc..1c584d3ccef959692639b9b5051e1a1616821431 100644 (file)
@@ -121,7 +121,7 @@ int xencons_ring_init(void)
            !xen_start_info->console.domU.evtchn)
                return -ENODEV;
 
-       irq = bind_evtchn_to_irqhandler(
+       irq = bind_caller_port_to_irqhandler(
                xen_start_info->console.domU.evtchn,
                handle_input, 0, "xencons", NULL);
        if (irq < 0) {
index 09f5ee5e1e784c594e7999aa79786a29b7677c1c..c2c39438ff46c231a64a671d9aa18a7fa48c0add 100644 (file)
@@ -61,7 +61,14 @@ static int evtchn_to_irq[NR_EVENT_CHANNELS] = {
 static u32 irq_info[NR_IRQS];
 
 /* Binding types. */
-enum { IRQT_UNBOUND, IRQT_PIRQ, IRQT_VIRQ, IRQT_IPI, IRQT_EVTCHN };
+enum {
+       IRQT_UNBOUND,
+       IRQT_PIRQ,
+       IRQT_VIRQ,
+       IRQT_IPI,
+       IRQT_LOCAL_PORT,
+       IRQT_CALLER_PORT
+};
 
 /* Constructor for packed IRQ information. */
 static inline u32 mk_irq_info(u32 type, u32 index, u32 evtchn)
@@ -275,18 +282,18 @@ static int find_unbound_irq(void)
        return -ENOSPC;
 }
 
-static int bind_evtchn_to_irq(unsigned int evtchn)
+static int bind_caller_port_to_irq(unsigned int caller_port)
 {
        int irq;
 
        spin_lock(&irq_mapping_update_lock);
 
-       if ((irq = evtchn_to_irq[evtchn]) == -1) {
+       if ((irq = evtchn_to_irq[caller_port]) == -1) {
                if ((irq = find_unbound_irq()) < 0)
                        goto out;
 
-               evtchn_to_irq[evtchn] = irq;
-               irq_info[irq] = mk_irq_info(IRQT_EVTCHN, 0, evtchn);
+               evtchn_to_irq[caller_port] = irq;
+               irq_info[irq] = mk_irq_info(IRQT_CALLER_PORT, 0, caller_port);
        }
 
        irq_bindcount[irq]++;
@@ -296,6 +303,59 @@ static int bind_evtchn_to_irq(unsigned int evtchn)
        return irq;
 }
 
+static int bind_local_port_to_irq(unsigned int local_port)
+{
+       int irq;
+
+       spin_lock(&irq_mapping_update_lock);
+
+       BUG_ON(evtchn_to_irq[local_port] != -1);
+
+       if ((irq = find_unbound_irq()) < 0) {
+               struct evtchn_close close = { .port = local_port };
+               if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close))
+                       BUG();
+               goto out;
+       }
+
+       evtchn_to_irq[local_port] = irq;
+       irq_info[irq] = mk_irq_info(IRQT_LOCAL_PORT, 0, local_port);
+       irq_bindcount[irq]++;
+
+ out:
+       spin_unlock(&irq_mapping_update_lock);
+       return irq;
+}
+
+static int bind_listening_port_to_irq(unsigned int remote_domain)
+{
+       struct evtchn_alloc_unbound alloc_unbound;
+       int err;
+
+       alloc_unbound.dom        = DOMID_SELF;
+       alloc_unbound.remote_dom = remote_domain;
+
+       err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
+                                         &alloc_unbound);
+
+       return err ? : bind_local_port_to_irq(alloc_unbound.port);
+}
+
+static int bind_interdomain_evtchn_to_irq(unsigned int remote_domain,
+                                         unsigned int remote_port)
+{
+       struct evtchn_bind_interdomain bind_interdomain;
+       int err;
+
+       bind_interdomain.remote_dom  = remote_domain;
+       bind_interdomain.remote_port = remote_port;
+
+       err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+                                         &bind_interdomain);
+
+       return err ? : bind_local_port_to_irq(bind_interdomain.local_port);
+}
+
 static int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
 {
        struct evtchn_bind_virq bind_virq;
@@ -370,7 +430,8 @@ static void unbind_from_irq(unsigned int irq)
 
        if ((--irq_bindcount[irq] == 0) && VALID_EVTCHN(evtchn)) {
                close.port = evtchn;
-               if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0)
+               if ((type_from_irq(irq) != IRQT_CALLER_PORT) &&
+                   HYPERVISOR_event_channel_op(EVTCHNOP_close, &close))
                        BUG();
 
                switch (type_from_irq(irq)) {
@@ -396,17 +457,39 @@ static void unbind_from_irq(unsigned int irq)
        spin_unlock(&irq_mapping_update_lock);
 }
 
-int bind_evtchn_to_irqhandler(
-       unsigned int evtchn,
+int bind_caller_port_to_irqhandler(
+       unsigned int caller_port,
+       irqreturn_t (*handler)(int, void *, struct pt_regs *),
+       unsigned long irqflags,
+       const char *devname,
+       void *dev_id)
+{
+       int irq, retval;
+
+       irq = bind_caller_port_to_irq(caller_port);
+       if (irq < 0)
+               return irq;
+
+       retval = request_irq(irq, handler, irqflags, devname, dev_id);
+       if (retval != 0) {
+               unbind_from_irq(irq);
+               return retval;
+       }
+
+       return irq;
+}
+EXPORT_SYMBOL_GPL(bind_caller_port_to_irqhandler);
+
+int bind_listening_port_to_irqhandler(
+       unsigned int remote_domain,
        irqreturn_t (*handler)(int, void *, struct pt_regs *),
        unsigned long irqflags,
        const char *devname,
        void *dev_id)
 {
-       unsigned int irq;
-       int retval;
+       int irq, retval;
 
-       irq = bind_evtchn_to_irq(evtchn);
+       irq = bind_listening_port_to_irq(remote_domain);
        if (irq < 0)
                return irq;
 
@@ -418,7 +501,31 @@ int bind_evtchn_to_irqhandler(
 
        return irq;
 }
-EXPORT_SYMBOL_GPL(bind_evtchn_to_irqhandler);
+EXPORT_SYMBOL_GPL(bind_listening_port_to_irqhandler);
+
+int bind_interdomain_evtchn_to_irqhandler(
+       unsigned int remote_domain,
+       unsigned int remote_port,
+       irqreturn_t (*handler)(int, void *, struct pt_regs *),
+       unsigned long irqflags,
+       const char *devname,
+       void *dev_id)
+{
+       int irq, retval;
+
+       irq = bind_interdomain_evtchn_to_irq(remote_domain, remote_port);
+       if (irq < 0)
+               return irq;
+
+       retval = request_irq(irq, handler, irqflags, devname, dev_id);
+       if (retval != 0) {
+               unbind_from_irq(irq);
+               return retval;
+       }
+
+       return irq;
+}
+EXPORT_SYMBOL_GPL(bind_interdomain_evtchn_to_irqhandler);
 
 int bind_virq_to_irqhandler(
        unsigned int virq,
@@ -428,8 +535,7 @@ int bind_virq_to_irqhandler(
        const char *devname,
        void *dev_id)
 {
-       unsigned int irq;
-       int retval;
+       int irq, retval;
 
        irq = bind_virq_to_irq(virq, cpu);
        if (irq < 0)
@@ -453,8 +559,7 @@ int bind_ipi_to_irqhandler(
        const char *devname,
        void *dev_id)
 {
-       unsigned int irq;
-       int retval;
+       int irq, retval;
 
        irq = bind_ipi_to_irq(ipi, cpu);
        if (irq < 0)
@@ -729,6 +834,12 @@ void notify_remote_via_irq(int irq)
 }
 EXPORT_SYMBOL_GPL(notify_remote_via_irq);
 
+int irq_to_evtchn_port(int irq)
+{
+       return evtchn_from_irq(irq);
+}
+EXPORT_SYMBOL_GPL(irq_to_evtchn_port);
+
 void mask_evtchn(int port)
 {
        shared_info_t *s = HYPERVISOR_shared_info;
index 54f7b5c509908df56aa67b82ca8942a2b3249da7..40846d1d09e7644e5fc7fd19cf1011e069fbc0bc 100644 (file)
@@ -56,7 +56,6 @@ struct xenfb_info
        struct page             **pages;
        struct list_head        mappings; /* protected by mm_lock */
 
-       unsigned                evtchn;
        int                     irq;
        struct xenfb_page       *page;
        unsigned long           *mfns;
@@ -156,7 +155,7 @@ static void xenfb_do_update(struct xenfb_info *info,
        wmb();                  /* ensure ring contents visible */
        info->page->out_prod = prod + 1;
 
-       notify_remote_via_evtchn(info->evtchn);
+       notify_remote_via_irq(info->irq);
 }
 
 static int xenfb_queue_full(struct xenfb_info *info)
@@ -429,7 +428,7 @@ static irqreturn_t xenfb_event_handler(int rq, void *dev_id,
 
        if (page->in_cons != page->in_prod) {
                info->page->in_cons = info->page->in_prod;
-               notify_remote_via_evtchn(info->evtchn);
+               notify_remote_via_irq(info->irq);
        }
        return IRQ_HANDLED;
 }
@@ -618,14 +617,11 @@ static int xenfb_connect_backend(struct xenbus_device *dev,
        int ret;
        struct xenbus_transaction xbt;
 
-       ret = xenbus_alloc_evtchn(dev, &info->evtchn);
-       if (ret)
-               return ret;
-       ret = bind_evtchn_to_irqhandler(info->evtchn, xenfb_event_handler,
-                                       0, "xenfb", info);
+       ret = bind_listening_port_to_irqhandler(
+               dev->otherend_id, xenfb_event_handler, 0, "xenfb", info);
        if (ret < 0) {
-               xenbus_free_evtchn(dev, info->evtchn);
-               xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler");
+               xenbus_dev_fatal(dev, ret,
+                                "bind_listening_port_to_irqhandler");
                return ret;
        }
        info->irq = ret;
@@ -641,7 +637,7 @@ static int xenfb_connect_backend(struct xenbus_device *dev,
        if (ret)
                goto error_xenbus;
        ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
-                           info->evtchn);
+                           irq_to_evtchn_port(info->irq));
        if (ret)
                goto error_xenbus;
        ret = xenbus_printf(xbt, dev->nodename, "feature-update", "1");
index 7737732e34ec655b6ab67a9bebbbcc3856d89c9d..e4debd83d35e504d2086427e4c6a8fe3ec602089 100644 (file)
@@ -31,7 +31,6 @@ struct xenkbd_info
 {
        struct input_dev *dev;
        struct xenkbd_page *page;
-       unsigned evtchn;
        int irq;
        struct xenbus_device *xbdev;
 };
@@ -76,7 +75,7 @@ static irqreturn_t input_handler(int rq, void *dev_id, struct pt_regs *regs)
        input_sync(info->dev);
        mb();                   /* ensure we got ring contents */
        page->in_cons = cons;
-       notify_remote_via_evtchn(info->evtchn);
+       notify_remote_via_irq(info->irq);
 
        return IRQ_HANDLED;
 }
@@ -168,14 +167,11 @@ static int xenkbd_connect_backend(struct xenbus_device *dev,
        int ret;
        struct xenbus_transaction xbt;
 
-       ret = xenbus_alloc_evtchn(dev, &info->evtchn);
-       if (ret)
-               return ret;
-       ret = bind_evtchn_to_irqhandler(info->evtchn, input_handler, 0,
-                                       "xenkbd", info);
+       ret = bind_listening_port_to_irqhandler(
+               dev->otherend_id, input_handler, 0, "xenkbd", info);
        if (ret < 0) {
-               xenbus_free_evtchn(dev, info->evtchn);
-               xenbus_dev_fatal(dev, ret, "bind_evtchn_to_irqhandler");
+               xenbus_dev_fatal(dev, ret,
+                                "bind_listening_port_to_irqhandler");
                return ret;
        }
        info->irq = ret;
@@ -191,7 +187,7 @@ static int xenkbd_connect_backend(struct xenbus_device *dev,
        if (ret)
                goto error_xenbus;
        ret = xenbus_printf(xbt, dev->nodename, "event-channel", "%u",
-                           info->evtchn);
+                           irq_to_evtchn_port(info->irq));
        if (ret)
                goto error_xenbus;
        ret = xenbus_transaction_end(xbt, 0);
index 367c008d3bb4eed46b981ed4384e83c6af7b8101..e0537e52ff22a3c3e0a8debdd1f91853e0b7563c 100644 (file)
@@ -67,7 +67,6 @@ typedef struct netif_st {
        grant_ref_t      tx_shmem_ref;
        grant_handle_t   rx_shmem_handle;
        grant_ref_t      rx_shmem_ref;
-       unsigned int     evtchn;
        unsigned int     irq;
 
        /* The shared rings and indexes. */
index 9fae954bd200ea417f7fed25fe0cdb4493b90880..4596fedce8d44d7853154ffd590c99c1eb964008 100644 (file)
@@ -259,7 +259,6 @@ int netif_map(netif_t *netif, unsigned long tx_ring_ref,
        int err = -ENOMEM;
        netif_tx_sring_t *txs;
        netif_rx_sring_t *rxs;
-       struct evtchn_bind_interdomain bind_interdomain;
 
        /* Already connected through? */
        if (netif->irq)
@@ -276,18 +275,12 @@ int netif_map(netif_t *netif, unsigned long tx_ring_ref,
        if (err)
                goto err_map;
 
-       bind_interdomain.remote_dom = netif->domid;
-       bind_interdomain.remote_port = evtchn;
-
-       err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
-                                         &bind_interdomain);
-       if (err)
+       err = bind_interdomain_evtchn_to_irqhandler(
+               netif->domid, evtchn, netif_be_int, 0,
+               netif->dev->name, netif);
+       if (err < 0)
                goto err_hypervisor;
-
-       netif->evtchn = bind_interdomain.local_port;
-
-       netif->irq = bind_evtchn_to_irqhandler(
-               netif->evtchn, netif_be_int, 0, netif->dev->name, netif);
+       netif->irq = err;
        disable_irq(netif->irq);
 
        txs = (netif_tx_sring_t *)netif->tx_comms_area->addr;
index 905880fdfaef571eba6dcaa5432d270fa40fba02..448a972cc428336f26b666efb632d692a2f0b532 100644 (file)
@@ -153,7 +153,7 @@ struct netfront_info {
        spinlock_t   tx_lock;
        spinlock_t   rx_lock;
 
-       unsigned int evtchn, irq;
+       unsigned int irq;
        unsigned int copying_receiver;
 
        /* Receive-ring batched refills. */
@@ -408,7 +408,8 @@ again:
                goto abort_transaction;
        }
        err = xenbus_printf(xbt, dev->nodename,
-                           "event-channel", "%u", info->evtchn);
+                           "event-channel", "%u",
+                           irq_to_evtchn_port(info->irq));
        if (err) {
                message = "writing event-channel";
                goto abort_transaction;
@@ -513,17 +514,15 @@ static int setup_device(struct xenbus_device *dev, struct netfront_info *info)
        }
        info->rx_ring_ref = err;
 
-       err = xenbus_alloc_evtchn(dev, &info->evtchn);
-       if (err)
-               goto fail;
-
        memcpy(netdev->dev_addr, info->mac, ETH_ALEN);
-       err = bind_evtchn_to_irqhandler(info->evtchn, netif_int,
-                                       SA_SAMPLE_RANDOM, netdev->name,
-                                       netdev);
+
+       err = bind_listening_port_to_irqhandler(
+               dev->otherend_id, netif_int, SA_SAMPLE_RANDOM, netdev->name,
+               netdev);
        if (err < 0)
                goto fail;
        info->irq = err;
+
        return 0;
 
  fail:
@@ -2029,7 +2028,7 @@ static void netif_disconnect_backend(struct netfront_info *info)
 
        if (info->irq)
                unbind_from_irqhandler(info->irq, info->netdev);
-       info->evtchn = info->irq = 0;
+       info->irq = 0;
 
        end_access(info->tx_ring_ref, info->tx.sring);
        end_access(info->rx_ring_ref, info->rx.sring);
index 0026753381a521c3433e33520ce1cd5ed56343dc..3ebd4b1e5af3662402100235060240f8a99eeca4 100644 (file)
@@ -71,7 +71,6 @@ static int pciback_do_attach(struct pciback_device *pdev, int gnt_ref,
                             int remote_evtchn)
 {
        int err = 0;
-       int evtchn;
        struct vm_struct *area;
 
        dev_dbg(&pdev->xdev->dev,
@@ -86,12 +85,9 @@ static int pciback_do_attach(struct pciback_device *pdev, int gnt_ref,
        pdev->sh_area = area;
        pdev->sh_info = area->addr;
 
-       err = xenbus_bind_evtchn(pdev->xdev, remote_evtchn, &evtchn);
-       if (err)
-               goto out;
-
-       err = bind_evtchn_to_irqhandler(evtchn, pciback_handle_event,
-                                       SA_SAMPLE_RANDOM, "pciback", pdev);
+       err = bind_interdomain_evtchn_to_irqhandler(
+               pdev->xdev->otherend_id, remote_evtchn, pciback_handle_event,
+               SA_SAMPLE_RANDOM, "pciback", pdev);
        if (err < 0) {
                xenbus_dev_fatal(pdev->xdev, err,
                                 "Error binding event channel to IRQ");
index b209b4f583e60dd77ef1e1d2a54666b7539b3627..d28eb31fddc413cebdfe05e9cd8f2f7d0adb2edb 100644 (file)
@@ -30,7 +30,6 @@ typedef struct tpmif_st {
        unsigned int handle;
 
        /* Physical parameters of the comms window. */
-       unsigned int evtchn;
        unsigned int irq;
 
        /* The shared rings and indexes. */
index 2614aa51269b91a1d0f42331a21a28af3100f7f7..a9b66db1ac2da1f190c688cb7c5daa7ee2be714d 100644 (file)
@@ -118,11 +118,9 @@ static void unmap_frontend_page(tpmif_t *tpmif)
 int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
 {
        int err;
-       struct evtchn_bind_interdomain bind_interdomain;
 
-       if (tpmif->irq) {
+       if (tpmif->irq)
                return 0;
-       }
 
        if ((tpmif->tx_area = alloc_vm_area(PAGE_SIZE)) == NULL)
                return -ENOMEM;
@@ -133,24 +131,17 @@ int tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
                return err;
        }
 
+       tpmif->tx = (tpmif_tx_interface_t *)tpmif->tx_area->addr;
 
-       bind_interdomain.remote_dom  = tpmif->domid;
-       bind_interdomain.remote_port = evtchn;
-
-       err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
-                                         &bind_interdomain);
-       if (err) {
+       err = bind_interdomain_evtchn_to_irqhandler(
+               tpmif->domid, evtchn, tpmif_be_int, 0, tpmif->devname, tpmif);
+       if (err < 0) {
                unmap_frontend_page(tpmif);
                free_vm_area(tpmif->tx_area);
                return err;
        }
+       tpmif->irq = err;
 
-       tpmif->evtchn = bind_interdomain.local_port;
-
-       tpmif->tx = (tpmif_tx_interface_t *)tpmif->tx_area->addr;
-
-       tpmif->irq = bind_evtchn_to_irqhandler(
-               tpmif->evtchn, tpmif_be_int, 0, tpmif->devname, tpmif);
        tpmif->shmem_ref = shared_page;
        tpmif->active = 1;
 
index a11140bda0f0124cea89025f8b69436f38a0ea0c..f294ec1cc9fb8e455653f33c513e70cdb0276d24 100644 (file)
@@ -254,28 +254,6 @@ int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port)
 EXPORT_SYMBOL_GPL(xenbus_alloc_evtchn);
 
 
-int xenbus_bind_evtchn(struct xenbus_device *dev, int remote_port, int *port)
-{
-       struct evtchn_bind_interdomain bind_interdomain;
-       int err;
-
-       bind_interdomain.remote_dom  = dev->otherend_id;
-       bind_interdomain.remote_port = remote_port,
-
-       err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
-                                         &bind_interdomain);
-       if (err)
-               xenbus_dev_fatal(dev, err,
-                                "binding to event channel %d from domain %d",
-                                remote_port, dev->otherend_id);
-       else
-               *port = bind_interdomain.local_port;
-
-       return err;
-}
-EXPORT_SYMBOL_GPL(xenbus_bind_evtchn);
-
-
 int xenbus_free_evtchn(struct xenbus_device *dev, int port)
 {
        struct evtchn_close close;
index e5af661c876ee6f9f03a1285cf5b1d1aeb91e8d8..b758c9f676edd9c845ed8cb579e96c4d0e3e2a20 100644 (file)
@@ -196,7 +196,7 @@ int xb_init_comms(void)
        if (xenbus_irq)
                unbind_from_irqhandler(xenbus_irq, &xb_waitq);
 
-       err = bind_evtchn_to_irqhandler(
+       err = bind_caller_port_to_irqhandler(
                xen_store_evtchn, wake_waiting,
                0, "xenbus", &xb_waitq);
        if (err <= 0) {
index 4f111ae19bf2261445c2dc766ab62e0e08a12fe0..a579cdf100f9a277e7f75503eae139ea35ca9331 100644 (file)
  * The IRQ argument passed to the callback handler is the same as returned
  * from the bind call. It may not correspond to a Linux IRQ number.
  * Returns IRQ or negative errno.
- * UNBIND: Takes IRQ to unbind from; automatically closes the event channel.
  */
-extern int bind_evtchn_to_irqhandler(
-       unsigned int evtchn,
+int bind_caller_port_to_irqhandler(
+       unsigned int caller_port,
        irqreturn_t (*handler)(int, void *, struct pt_regs *),
        unsigned long irqflags,
        const char *devname,
        void *dev_id);
-extern int bind_virq_to_irqhandler(
+int bind_listening_port_to_irqhandler(
+       unsigned int remote_domain,
+       irqreturn_t (*handler)(int, void *, struct pt_regs *),
+       unsigned long irqflags,
+       const char *devname,
+       void *dev_id);
+int bind_interdomain_evtchn_to_irqhandler(
+       unsigned int remote_domain,
+       unsigned int remote_port,
+       irqreturn_t (*handler)(int, void *, struct pt_regs *),
+       unsigned long irqflags,
+       const char *devname,
+       void *dev_id);
+int bind_virq_to_irqhandler(
        unsigned int virq,
        unsigned int cpu,
        irqreturn_t (*handler)(int, void *, struct pt_regs *),
        unsigned long irqflags,
        const char *devname,
        void *dev_id);
-extern int bind_ipi_to_irqhandler(
+int bind_ipi_to_irqhandler(
        unsigned int ipi,
        unsigned int cpu,
        irqreturn_t (*handler)(int, void *, struct pt_regs *),
@@ -77,21 +89,21 @@ extern int bind_ipi_to_irqhandler(
 
 /*
  * Common unbind function for all event sources. Takes IRQ to unbind from.
- * Automatically closes the underlying event channel (even for bindings
- * made with bind_evtchn_to_irqhandler()).
+ * Automatically closes the underlying event channel (except for bindings
+ * made with bind_caller_port_to_irqhandler()).
  */
-extern void unbind_from_irqhandler(unsigned int irq, void *dev_id);
+void unbind_from_irqhandler(unsigned int irq, void *dev_id);
 
-extern void irq_resume(void);
+void irq_resume(void);
 
 /* Entry point for notifications into Linux subsystems. */
 asmlinkage void evtchn_do_upcall(struct pt_regs *regs);
 
 /* Entry point for notifications into the userland character device. */
-extern void evtchn_device_upcall(int port);
+void evtchn_device_upcall(int port);
 
-extern void mask_evtchn(int port);
-extern void unmask_evtchn(int port);
+void mask_evtchn(int port);
+void unmask_evtchn(int port);
 
 static inline void clear_evtchn(int port)
 {
@@ -106,9 +118,10 @@ static inline void notify_remote_via_evtchn(int port)
 }
 
 /*
- * Unlike notify_remote_via_evtchn(), this is safe to use across
- * save/restore. Notifications on a broken connection are silently dropped.
+ * Use these to access the event channel underlying the IRQ handle returned
+ * by bind_*_to_irqhandler().
  */
-extern void notify_remote_via_irq(int irq);
+void notify_remote_via_irq(int irq);
+int irq_to_evtchn_port(int irq);
 
 #endif /* __ASM_EVTCHN_H__ */
index c7cb7eaa3adf876cf286672a15c688f7bd894b8e..3f525fa2dd7c646199aa099c131ba23a507b7a93 100644 (file)
@@ -261,14 +261,6 @@ int xenbus_unmap_ring(struct xenbus_device *dev,
 int xenbus_alloc_evtchn(struct xenbus_device *dev, int *port);
 
 
-/**
- * Bind to an existing interdomain event channel in another domain. Returns 0
- * on success and stores the local port in *port. On error, returns -errno,
- * switches the device to XenbusStateClosing, and saves the error in XenStore.
- */
-int xenbus_bind_evtchn(struct xenbus_device *dev, int remote_port, int *port);
-
-
 /**
  * Free an existing event channel. Returns 0 on success or -errno on error.
  */